using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using MoEngine;
using System.Diagnostics;
using MoGameLib.BattleStates;

namespace MoGameLib
{
    public static class BattleRotation
    {
        public static float North { get { return 180; } }
        public static float South { get { return 0; } }
        public static float West { get { return 90; } }
        public static float East { get { return -90; } }
    }

    public enum BattleSide
    {
        Left,
        Right
    }

    public class Battle
    {
        private BattleMap m_Map;

        public BattleMap Map
        {
            get { return m_Map; }
        }

        protected StateManager<BattleState> StateMgr = new StateManager<BattleState>();

        public Battle(BattleMap map)
        {
            InitBattleStates();
            m_Map = map;
        }

        protected List<Battler> m_Battlers = new List<Battler>();

        public Battler CreateBattler(Creature creature, BattleTeam team, Vector2Int tileLoc)
        {
            if (team == null)
                throw new Exception("Battler must have a team!");

            Battler new_battler = new Battler(this, creature);
            new_battler.Team = team;
            new_battler.TileLocaction = tileLoc;
            AddBattler(new_battler);
            return new_battler;
        }

        protected void AddBattler(Battler battler)
        {
            m_Battlers.Add(battler);
            // add to map
            m_Map.AddBattler(battler);
        }

        protected List<BattlePawn> m_Pawns = new List<BattlePawn>();

        public void AddPawn(BattlePawn pawn)
        {
            m_Pawns.Add(pawn);

            m_IdlePawns[(int)pawn.Side].Add(pawn);
        }


        protected List<BattleTeam> m_Teams = new List<BattleTeam>();

        public BattleTeam CreateTeam(Player player)
        {
            BattleTeam new_team = new BattleTeam();
            new_team.Player = player;
            m_Teams.Add(new_team);
            return new_team;
        }


        private WindowBattle m_BattleWnd;

        public WindowBattle BattleWindow
        {
            set { m_BattleWnd = value; }
        }

        private bool m_bActive;

        public bool IsActive
        {
            get { return m_bActive; }
        }

        public virtual void Start()
        {
            m_bActive = true;

            // initialize 

            // go to first turn
            NextTurn();


            // GotoState(BattleStates.NextPawn);
        }

        public virtual void Update(GameTime gameTime)
        {
            StateMgr.Update(gameTime);
        }


        protected List<BattlePawn> m_BattleQueue = new List<BattlePawn>();
        protected List<BattlePawn>[] m_IdlePawns = { new List<BattlePawn>(), new List<BattlePawn>()};

        public IEnumerable<BattlePawn> IdlePawns(BattleSide side)
        {
            return m_IdlePawns[(int)side];
        }

        public void NextTurn()
        {
            // setup pawn orders, fill out battle queue
            // current imp -- based on initiative
            //m_BattleQueue.AddRange(m_Pawns);

            // next pawn
            //NextPawn();
            m_BattleWnd.StartOrderPhase();
            GotoState(typeof(StateGivingOrders));
        }

        public void Run()
        {
            GotoState(typeof(StateRunning));
        }

        public void Pause()
        {
            NextTurn();
        }

        //protected BattlePawn m_CurrentPawn; 
/*
        public void NextPawn()
        {
            if (m_BattleQueue.Count <= 0)
            {
                NextTurn();
            }
            else
            {
                m_CurrentPawn = m_BattleQueue[0];
                m_BattleQueue.RemoveAt(0);
                m_BattleWnd.StartPlay(m_CurrentPawn);
                GotoState(BattleStates.WaitingForOrders);
            }
        }*/

        #region State Code

        protected virtual void InitBattleStates()
        {
            StateMgr.AddState(new StateGivingOrders(), this);
            StateMgr.AddState(new StateRunning(), this);


            /*
            state = m_StateMgr.NewState((int)BattleStates.GivingOrders);
            state.UpdateFunc = delegate(GameTime gameTime)
            {
                //m_BattleWnd.StartPlay(m_Battlers[0], "My blade is ready to taste the blood of those goblins!", gameTime);
                //GotoState(BattleStates.WaitingForOrders);
            };

            state = m_StateMgr.NewState((int)BattleStates.Running);
            state.UpdateFunc = delegate(GameTime gameTime)
            {

            };*/
        }

        protected void GotoState(Type state)
        {
            StateMgr.GotoState(state);
        }

        #endregion

    }

    public class BattleState : State
    {
        protected Battle Battle;

        public override void Init(object host, BaseStateManager stateManager)
        {
            base.Init(host, stateManager);

            Battle = host as Battle;
        }
    }

    namespace BattleStates
    {
        internal class StateGivingOrders : BattleState
        {

        }
        internal class StateRunning : BattleState
        {
            private double startSeconds;

            public override void BeginState(State prevState)
            {
                base.BeginState(prevState);
                startSeconds = Core.ClockMgr.TotalGameTime.TotalSeconds;
            }

            public override void Update(GameTime gameTime)
            {
                //if (gameTime.TotalGameTime.TotalSeconds - startSeconds > 10.0)
                //{
                //    Battle.NextTurn();
                //}

                base.Update(gameTime);
                Battle.Map.Update(gameTime);
            }
        }
    }


}
